package org.testile.datasetgenerifier.impl;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import java.util.List;
import org.testile.datasetgenerifier.ColumnGenerifier;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 *
 * @author ytoh
 */
public class DefaultColumnGenerifier implements ColumnGenerifier {
	private Function<String,String> transformation;
	private List<Function<String, String>> transformations;
	private boolean composed = false;

	public DefaultColumnGenerifier() {
		this(Lists.<Function<String,String>>newArrayList());
	}

	public DefaultColumnGenerifier(List<Function<String, String>> transformations) {
		checkNotNull(transformations, "Transformations cannot be null");
		this.transformations = transformations;

		if(transformations.size() == 0) {
			transformation = Functions.identity();
			composed = true;
		}
	}

	private Function<String, String> composeTransformations(List<Function<String, String>> transformations) {
		int size = transformations.size();
		if(size == 1) {
			return transformations.get(0);
		}

		Function<String,String> composedFunction = Iterators.getLast(transformations.iterator());
		for (Function<String, String> function : Iterables.reverse(transformations.subList(0, size - 1))) {
			composedFunction = Functions.compose(composedFunction, function);
		}
		return composedFunction;
	}

	public void addTransformation(Function<String,String> transformation) {
		checkNotNull(transformation, "Transformation cannot be null");
		composed = false;

		transformations.add(transformation);
	}

	public String generifyValue(String input) {
		if (!composed) {
			transformation = composeTransformations(transformations);
		}

		return transformation.apply(input);
	}
}
